#include "util.h"
#include "textgraphics.h"
#include "string.h"

static void put_string(const char* s, uint& pos)
{
  for (char c = *s; c != '\0'; ++s, c = *s)
    text_graphics::put_char(c, pos++);
}
#define put_char(CH) { text_graphics::put_char(CH, pos++); }

namespace util
{
  void dump_mem(uint8_t* start, uint8_t* end, uint initial_pos)
  {
    const unsigned int cols = 16;
    uint pos = initial_pos;

    uint offset = 0;
    int8_t string[0xFF];
    while (start < end)
    {
      put_string(string::from_int_to_hexadecimal_string(offset, string, 8), pos);
      put_string("  ", pos);

      // Print start row view
      for (uint i = 0; i < cols; ++i)
      {
        uint8_t byte = *((uint8_t*)start);
        put_string(string::from_int_to_hexadecimal_string(byte, string, 2), pos);
        put_char(' ');

        if (i == (cols / 2) - 1)
          put_char(' ');

        ++start;

        if (start == end)
        {
          start += (cols - i - 1);

          for (++i; i < cols; ++i)
            put_string("   ", pos);

          break;
        }
      }

      start -= cols;

      put_char(' ');

      // Print ascii row view
      for (uint i = 0; i < cols; ++i)
      {
        if (string::is_char_symbol(*((int8_t*)start)))
          put_char(*((int8_t*)start))
        else
          put_char('.');

        ++start;

        if (start == end)
          break;
      }

      pos += (text_graphics::cols() - (pos % text_graphics::cols()));

      offset += 16;
    }
  }
}
